﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using Caliburn.Micro;
using MediaOwl.WebSearch.TranslatorService;

namespace MediaOwl.WebSearch.Data.Translation
{
    public class GetAvailableLanguages : IResult
    {
        private readonly Action<IDictionary<string, string>, IEnumerable<string>> onSuccess;
        private readonly Action<Exception> onFail;
        private readonly LanguageServiceClient svcClient;
        private IEnumerable<string> speakLanguages; 

        public GetAvailableLanguages(Action<IDictionary<string, string>, IEnumerable<string>> onSuccess, Action<Exception> onFail = null)
        {
            svcClient = new LanguageServiceClient();
            this.onSuccess = onSuccess;
            this.onFail = onFail;
        }

        public void Execute(ActionExecutionContext context)
        {
            svcClient.GetLanguagesForSpeakCompleted += (s, e) =>
                                                           {
                                                               if (e.Error == null)
                                                               {
                                                                   speakLanguages = e.Result;
                                                                   GetLanguageNames();
                                                               }
                                                               else
                                                               {
                                                                   if (onFail != null)
                                                                       Caliburn.Micro.Execute.OnUIThread(() => onFail(e.Error));
                                                                   Completed(this, new ResultCompletionEventArgs { Error = e.Error });
                                                               }
                                                           };

            svcClient.GetLanguagesForSpeakAsync(BingDataAccess.AppId);
        }

        private void GetLanguageNames()
        {
            svcClient.GetLanguagesForTranslateCompleted += (s, e) =>
            {
                if (e.Error == null)
                {
                    GetAccordingLanguages(e.Result);
                }
                else
                {
                    if (onFail != null)
                        Caliburn.Micro.Execute.OnUIThread(() => onFail(e.Error));
                    Completed(this, new ResultCompletionEventArgs { Error = e.Error });
                }
            };

            svcClient.GetLanguagesForTranslateAsync(BingDataAccess.AppId);
        }

        private void GetAccordingLanguages(ObservableCollection<string> languageCodes)
        {
            svcClient.GetLanguageNamesCompleted += (s, e) =>
                                                       {
                                                           if (e.Error == null)
                                                           {
                                                               var dictionary =languageCodes.Zip(e.Result, (k, v) => new {k, v}).ToDictionary(x => x.k, x => x.v);

                                                               if (onSuccess != null)
                                                                   Caliburn.Micro.Execute.OnUIThread(() => onSuccess(dictionary, speakLanguages));
                                                           }
                                                           else
                                                           {
                                                               if (onFail != null)
                                                                   Caliburn.Micro.Execute.OnUIThread(() => onFail(e.Error));
                                                           }
                                                           Completed(this, new ResultCompletionEventArgs { Error = e.Error });
                                                       };

            svcClient.GetLanguageNamesAsync(BingDataAccess.AppId, CultureInfo.CurrentCulture.TwoLetterISOLanguageName, languageCodes);
        }

        public event EventHandler<ResultCompletionEventArgs> Completed = delegate {};
    }
}